# File: Effects.py
# Copyright 2010 
# Author: Andrew Dorrycott
# License: GNU Lesser General Public License
# Original Repository: http://code.google.com/p/bobthezombie/

import sys
import pygame
import random
import datetime
import math

from Standard import *

class Effect(WorldObject):
    def __init__(self, x, y, engine, view_image = IMAGES_BOB['CollisionMask'], collision_image = IMAGES_BOB['CollisionMask'], scale = 1.0, rotate_n_degrees = 0):
        WorldObject.__init__(self, x, y, engine, view_image, collision_image, scale)
        
        # Default is 20 but needs to change per effect
        self.age_limit = 20.0
        self.current_age = 0
        self.should_fade = True
        
        self.RotateImage(rotate_n_degrees)

    def Redraw(self, screen):
        if self.should_fade:
            # Change the alpha for fadding effect
            alpha = 255 * ( 1 - float(self.current_age) / float(self.age_limit) )
            self.view_image.set_alpha(alpha)
        
        # Call super class to take care of the rest
        WorldObject.Redraw(self, screen)

    def RotateImage(self, degrees):
        self.view_image = pygame.transform.rotate(self.view_image, degrees)
        self.image = pygame.transform.rotate(self.image, degrees)
    
    def UpdateImageLocation(self, pos1, pos2 = None):
        if type(pos1) == tuple:
            self.view_rectangle.x += pos1[0]
            self.view_rectangle.y += pos1[1]
            self.rect.x += pos1[0]
            self.rect.y += pos1[1]
        elif type(pos1) == int and type(pos2) == int:
            self.view_rectangle.x += pos1
            self.view_rectangle.y += pos2
            self.rect.x += pos1
            self.rect.y += pos2
    
    def GetCurrentAge(self):
        return self.current_age
    
    def GetAgeLimit(self):
        return self.age_limit
    
    def UpdateAge(self, tic):
        self.current_age += tic

class Pop(Effect):
    def __init__(self, x, y, engine, view_image = IMAGES_POP[1], collision_image = IMAGES_POP[1], scale = 1.0, rotate_n_degrees = 0, found_text = ""):
        Effect.__init__(self, x, y, engine, view_image, collision_image, scale, rotate_n_degrees)
        
        self.age_limit = 45
        self.found_text = found_text
    
    def Redraw(self, screen):
        Effect.Redraw(self, screen)
        
        # Add Found item text
        text = self.engine.font.render(self.found_text, 0, (255, 255, 255))
        screen.blit( text, (self.current_x - text.get_size()[0] / 2.0, self.current_y - 30) )

class DNAPartical(Effect):
    def __init__(self, x, y, engine, view_image = IMAGES_DNA, collision_image = IMAGES_DNA, scale = 1.0, rotate_n_degrees = 0):
        Effect.__init__(self, x, y, engine, view_image, collision_image, scale, rotate_n_degrees)
        
        # How far across the screen it should travel based on percentage of completed cure
        self.age_limit = random.random() * 800.0 * (self.engine.bob.cure / 100.0)
        self.radial_spin = int(5 * random.random())
        
        # The effect of fading out is nice
        self.should_fade = True
        
        if random.random() < 0.5:
            self.radial_spin *= -1 # Reverse the spin
    
    def Redraw(self, screen):
        #self.RotateImage(self.radial_spin) # Spin the partical for less consistent effects
        if self.age_limit > 0:
            Effect.Redraw(self, screen)
    
    def Move(self):
        self.rect = self.rect.move( [1, 0] )
        self.view_rectangle = self.view_rectangle.move( [1, 0] ) # Move a set speed only
    
    def MoveNorth(self, speed):
        return # Do not move this direction
    
    def MoveSouth(self, speed):
        return # Do not move this direction
    
    def MoveEast(self, speed):
        return # Do not move this direction
    
    def MoveWest(self, speed):
        return # Do not move this direction

class Bullet(Effect):
    def __init__(self, x, y, engine, view_image = IMAGES_BULLET[1], collision_image = IMAGES_BULLET[1], scale = 1.0, direction = None, damage = -5):
        Effect.__init__(self, x, y, engine, view_image, collision_image, scale)
        
        # Get the directional movement, facing image direction and starting location
        vector = [0, 0]
        BULLET_MOVEMENT_SPEED = 3
        self.should_fade = False
        
        if 'FaceNorth' in direction:
            vector[1] -= BULLET_MOVEMENT_SPEED
            self.UpdateImageLocation( 0, (( engine.bob.rect.size[1] / 2 ) + 5) * -1)
            self.RotateImage(-90)
            
            if 'FaceWest' in direction:
                vector[0] -= BULLET_MOVEMENT_SPEED
                self.UpdateImageLocation((( engine.bob.rect.size[0] / 2 ) + 5) * -1, 0)
                self.RotateImage(45)
            if 'FaceEast' in direction:
                vector[0] += BULLET_MOVEMENT_SPEED
                self.UpdateImageLocation(( engine.bob.rect.size[0] / 2 ) + 5, 0)
                self.RotateImage(-45)
            
        elif 'FaceSouth' in direction:
            vector[1] += BULLET_MOVEMENT_SPEED
            self.UpdateImageLocation( 0, ( engine.bob.rect.size[1] / 2 ) + 5)
            
            self.RotateImage(90)
            
            if 'FaceWest' in direction:
                vector[0] -= BULLET_MOVEMENT_SPEED
                self.UpdateImageLocation((( engine.bob.rect.size[0] / 2 ) + 5) * -1, 0)
                self.RotateImage(-45)
            if 'FaceEast' in direction:
                vector[0] += BULLET_MOVEMENT_SPEED
                self.UpdateImageLocation(( engine.bob.rect.size[0] / 2 ) + 5, 0)
                self.RotateImage(45)
            
        elif 'FaceWest' in direction:
            vector[0] -= BULLET_MOVEMENT_SPEED
            self.UpdateImageLocation((( engine.bob.rect.size[0] / 2 ) + 5) * -1, 0)
            
        elif 'FaceEast' in direction:
            vector[0] += BULLET_MOVEMENT_SPEED
            self.UpdateImageLocation(( engine.bob.rect.size[0] / 2 ) + 5, 0)
            self.RotateImage(180)
        
        self.vector = vector
        self.age_limit = 300
        
        # Default is -5 but will change depending on the bullet type
        self.damage = damage
    
    def CauseDamage(self, npc):
        npc.UpdateHealth(self.damage)
    
    def Redraw(self, screen):
        screen.blit(self.view_image, self.view_rectangle)
    
    def MoveBullet(self):
        self.view_rectangle = self.view_rectangle.move( self.vector )
        self.rect = self.rect.move( self.vector )
    
    def WillCollideWithBoundariesAt(self):
        # Find out if the object is running into Bob or the World
        return pygame.sprite.collide_mask(self.engine.bob, self) or \
            pygame.sprite.collide_mask(self.engine.world, self) or \
            self.engine.IsCollidingWithOtherNPCs(self)
        
        # This is quite interesting, the Super class has knowledge of Bob despite this class coming before Bob :)

class BulletPistol(Bullet):
    pass # default values in Bullet are set to pistol

class BulletRifle(Bullet):
    def __init__(self, x, y, engine, view_image = IMAGES_BULLET[1], collision_image = IMAGES_BULLET[1], scale = 1.0, direction = None, damage = -10):
        Bullet.__init__(self, x, y, engine, view_image, collision_image, scale, direction, damage)
        
        self.age_limit = 400

class BulletShotgun(Bullet):
    def __init__(self, x, y, engine, view_image = IMAGES_BULLET[1], collision_image = IMAGES_BULLET[1], scale = 1.0, direction = None, damage = -15):
        Bullet.__init__(self, x, y, engine, view_image, collision_image, scale, direction, damage)
        
        self.age_limit = 200

class BulletInfection(Bullet):
    def __init__(self, x, y, engine, view_image = IMAGES_BULLET[1], collision_image = IMAGES_BULLET[1], scale = 1.0, direction = None, damage = -4):
        Bullet.__init__(self, x, y, engine, view_image, collision_image, scale, direction, damage)
        
        # 1 Steps forward
        self.age_limit = 1
    
    def CauseDamage(self, npc):
        Bullet.CauseDamage(self, npc)
        
        # For the Swarm!
        npc.is_infected = True